package midas.mw.crt;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

import midas.mw.cfg.CfgError;
import midas.mw.cfg.CfgLogging;
import midas.mw.cfg.log.Logger;

/**
 * This class manages all the necessary parameters to make the CRT working.
 * Some of them are fixed values, others are retrieved for the
 * ConfigurationCRT.properties file.
 */
public class Constants
{
	/**
	 * Constructor
	 *
	 */
	public Constants()
	{
	}
	
	/**
	 * Value for Ethernet network interfaces.
	 */
	private static final int ETHERNET_TYPE				= 0;
	
	/**
	 * Value for 3G/UMTS network interfaces.
	 */
	private static final int THIRDG_TYPE				= 1;
	
	/**
	 * Value for WiFi network interfaces.
	 */
	private static final int WIFI_TYPE					= 2;
	
	/**
	 * Value for Bluetooth network interfaces.
	 */
	private static final int BT_TYPE 					= 3;
	
	/**
	 * Interval time to make polling to the CN
	 */
	private int POLLING_INTERVAL						= 0;
	
	/**
	 * Returns the time set to poll the CN
	 * @return The time set to poll the CN
	 */
	public int getPollingInterval()
	{
		return POLLING_INTERVAL;
	}
	
	/**
	 * Timeout to get a response form the CN 
	 */
	private int HTTP_TIMEOUT							= 0;
	
	/**
	 * Returns the time set to get a response from the CN
	 * @return The time set to get a response from the CN
	 */
	public int getHttpTimeout()
	{
		return HTTP_TIMEOUT;
	}
	
	/**
	 * Name (or usually IP address) of the proxy (if needed)
	 */
	private String PROXY_NAME								= "";
	
	/**
	 * Returns the name (or usually IP address) of the proxy (if needed)
	 * @return The name (or usually IP address) of the proxy (if needed)
	 */
	public String getProxyName()
	{
		return PROXY_NAME;
	}
	
	/**
	 * Proxy port (if needed)
	 */
	private String PROXY_PORT								= "";
	
	/**
	 * Returns the proxy port (if needed)
	 * @return The proxy port (if needed)
	 */
	public String getProxyPort()
	{
		return PROXY_PORT;
	}
	
	/**
	 * Describes the name of the Ethernet network interface.
	 */
	private String ETHERNET = "";
	
	/**
	 * Provides the name of the ethernet network interface established in the
	 * properties configuration file
	 * 
	 * @return The name of the ethernet network interface that has been
	 * 			configured in the properties configuration file	
	 */
	public String getEthernetInterface()
    {
    	return ETHERNET;
    }
	
	/**
	 * Describes the name of the 3G/UMTS network interface.
	 */
	private String THIRDG = "";
	
	/**
	 * Provides the name of the 3G/UMTS network interface established in the
	 * properties configuration file
	 * 
	 * @return The name of the 3G/UMTS network interface that has been
	 * 			configured in the properties configuration file	
	 */
	public String get3GInterface()
    {
    	return THIRDG;
    }
	
	/**
	 * Describes the name of the WiFi network interface.
	 */
	private String WIFI = "";
	
	/**
	 * Provides the name of the WiFi network interface established in the
	 * properties configuration file
	 * 
	 * @return The name of the WiFi network interface that has been
	 * 			configured in the properties configuration file	
	 */
	public String getWiFiInterface()
    {
    	return WIFI;
    }
	
	/**
	 * Describes the name of the Bluetooth network interface.
	 */
	private String BT = "";	
	
	/**
	 * Provides the name of the Bluetooth network interface established in the
	 * properties configuration file
	 * 
	 * @return The name of the Bluetooth network interface that has been
	 * 			configured in the properties configuration file	
	 */
	public String getBtInterface()
    {
    	return BT;
    }
	
	/**
	 * Static IP address for the wireless interface
	 */
	private String IP_ADDRESS = "";
	
	/**
	 * Provides the IP address of the WiFi network interface, to work in Ad-Hoc mode, 
	 * established in the properties configuration file. 
	 * 
	 * @return The IP address of the WiFi network interface to work in Ad-Hoc mode
	 * 			that has been configured in the properties configuration file.
	 */
	public String getIPAddress()
    {
    	return IP_ADDRESS;
    }
	
	/**
	 * Netmask address for the wireless interface
	 */
	private String NETMASK = "";
	
	/**
	 * Provides the subnet mask of the WiFi network interface, to work in 
	 * Ad-Hoc mode, established in the properties configuration file. 
	 * 
	 * @return The subnet mask of the WiFi network interface to work in Ad-Hoc 
	 * 			mode that has been configured in the properties configuration file.
	 */
	public String getNetMask()
    {
    	return NETMASK;
    }
	
	/**
	 * Network address for the wireless interface
	 */
	private String NET_ADDRESS = "";
	
	/**
	 * Provides the network address of the WiFi network interface, to work in 
	 * Ad-Hoc mode, established in the properties configuration file. 
	 * 
	 * @return The network address of the WiFi network interface to work in Ad-Hoc mode
	 * 			that has been configured in the properties configuration file.
	 */
	public String getNetAddress()
    {
    	return NET_ADDRESS;
    }
	
	/**
	 * SSID (Service Set Identifier) for the wireless interface
	 */
	private String SSID = "";
	
	/**
	 * Provides the SSID of the WiFi network interface established in the 
	 * properties configuration file. 
	 * 
	 * @return The SSID of the WiFi network interface that has been configured
	 * 			in the properties configuration file.
	 */
	public String getSSID()
    {
    	return SSID;
    }
	
	/**
	 * Mode for the wireless networking. It could be "infrastructure" or "ad hoc"
	 */
	private String MODE = "";
	
	/**
	 * Provides the wireless mode of the WiFi network interface established in 
	 * the properties configuration file. 
	 * 
	 * @return The wireless mode of the WiFi network interface that has been 
	 * 			configured in the properties configuration file.
	 */
	public String getMode()
    {
    	return MODE;
    }
	
	/**
	 * Encryption key for wireless communications
	 */
	private String KEY = "";
	
	/**
	 * Provides the key used to manipulate encryption in the communications 
	 * associated to the WiFi network interface established in the properties
	 * configuration file. The key will be enter as an ASCII string
	 * 
	 * @return The key used to encrypt the communications through the WiFi
	 * 			network interface that has been configured in the properties 
	 *			configuration file.
	 */
	public String getKey()
    {
    	return KEY;
    }
	
	/**
	 * MIDAS node identifier. It should be unique
	 */
	private String NODE_ID = "";
	
	/**
	 * Provides the MIDAS node identifier associated to a node that has been
	 * configured in the properties configuration file. 
	 * 
	 * @return The MIDAS node identifier of the node
	 */
	public String getNodeId()
    {
    	return NODE_ID;
    }
	
	/**
	 * IP address of the node acting as a proxy. Used in comminications through
	 * proxy
	 */
	private String CENTRAL_NODE_IP = "";
	
	/**
	 * Provides the IP address of the node acting as a proxy
	 * @return IP address of the node acting as a proxy
	 */
	public String getCentralNodeIP()
    {
    	return CENTRAL_NODE_IP;
    }
	
	/**
	 * IP address of the node acting as a proxy. Used in comminications through
	 * proxy
	 */
	private String PUBLIC_IP_ADDRESS = "";
	
	/**
	 * Provides the IP address of the node acting as a proxy
	 * @return IP address of the node acting as a proxy
	 */
	public String getPublicIPAddress()
    {
    	return PUBLIC_IP_ADDRESS;
    }
	
	/**
	 * Name of the file storing the parameters to initiate the CRT properly
	 */
	public static final String CONFIGURATION_FILE 	= "conf/ConfigurationCRT.properties";
	
	/**
	 * Field for showing the kind of message sent/received
	 */
	public static final String MESSAGE_TYPE			= "MESSAGE_TYPE";
    
	/**
	 * Value of the namespace for MIDAS messages
	 */
	public static final String MIDAS				= "MIDAS";
	
	/**
	 * Value for messages intended for showing new nodes in the network
	 */
	public static final String ACTION_ADD			= "ADD";
	
	/**
	 * Value for messages intended for showing nodes leaving the network
	 */
    public static final String ACTION_DELETE		= "DELETE";
    
    /**
	 * Value for messages intended for receiving notifications about the presence of other nodes in the network
	 */
    public static final String ACTION_SUBSCRIBE		= "SUBSCRIBE";
    
    /**
	 * Value for messages intended for stopping receiving notifications about the presence of other nodes in the network
	 */
    public static final String ACTION_UNSUBSCRIBE	= "UNSUBSCRIBE";
    
    /**
	 * Value for the service intended for receiving notifications about the presence of other nodes in the network
	 */
    public static final String PRESENCE_SERVICE		= "PRESENCE_SERVICE";
    
    /**
	 * Value for the service intended for receiving messages of other nodes in the network
	 */
    public static final String MESSAGE_SERVICE		= "MESSAGE_SERVICE";    
    
    /**
	 * Value for the service intended for receiving messages of other nodes in the network
	 */
    public static final String BROADCAST_MESSAGE_SERVICE = "BROADCAST_MESSAGE_SERVICE";
    
    /**
	 * Value to describe the message identifier
	 */
    public static final String MESSAGE_ID			= "MESSAGE_ID";

    /**
	 * Value to describe IP messages as requests
	 */
	public static final String IP_MESSAGE_BROADCAST 	= "IP_MESSAGE:BROADCAST";
	
    /**
	 * Value to describe IP messages as questions to Central Node
	 */
	public static final String IP_MESSAGE_QUESTION 	= "IP_MESSAGE:QUESTION";
	
	/**
	 * Value to describe IP messages as presence requests from Central Node
	 */
	public static final String IP_MESSAGE_PRESENCE 	= "IP_MESSAGE:PRESENCE";
    
    /**
	 * Value to describe IP messages as requests
	 */
	public static final String IP_MESSAGE_REQUEST 	= "IP_MESSAGE:REQUEST";
	
	/**
	 * Value to describe IP messages as responses
	 */
	public static final String IP_MESSAGE_RESPONSE 	= "IP_MESSAGE:RESPONSE";
	
	/**
	 * Value to describe CBR messages
	 */
	public static final String CBR_MESSAGE 			= "CBR_MESSAGE";
	
	/**
	 * Value to describe if the IPMessage needs delivery confirmation
	 */
	public static final String CONFIRMATION 		= "CONFIRMATION";
	
	/**
	 * Value to describe the node identifier of the source node
	 */
	public static final String SRC_NODE 			= "SRC_NODE";
	
	/**
	 * Value to describe the node identifier of the destination node
	 */
	public static final String DST_NODE 			= "DST_NODE";
	
	/**
	 * Value to describe the node identifier of the final destination node
	 */
	public static final String FINAL_DST_NODE 		= "FINAL_DST_NODE";
	
	/**
	 * Value to describe the name of the source application
	 */
	public static final String SRC_APP 				= "SRC_APP";
	
	/**
	 * Value to describe the name of the destination application
	 */
	public static final String DST_APP 				= "DST_APP";
	
	/**
	 * Value to describe the priority of the message
	 */
	public static final String PRIORITY 			= "PRIORITY";
	
	/**
	 * Value to describe the time to live of the message
	 */
	public static final String EXP_TIME 			= "EXP_TIME";
	
	/**
	 * Value to describe the length of the message
	 */
	public static final String TOTAL_LENGTH			= "TOTAL_LENGTH";
	
	/**
	 * Value to describe the number of messages taking part of the whole message 
	 */
	public static final String NUM_MESSAGES			= "NUM_MESSAGES";
	
	/**
	 * Value to describe the order of the message into the whole message  
	 */
	public static final String NUM_ORDER			= "NUM_ORDER";
	
	
	/**
	 * Value to describe the maximum length of the message  
	 */
	public static final int MAX_MESS_SIZE			= 65536;
	
	/**
	 * Value to describe the data stored in the message
	 */
	public static final String DATA 				= "DATA";
	
	/**
	 * Value to describe the JXTA identifier in a message
	 */
	public static final String JXTA_ID 				= "JXTA_ID";
	
	/**
	 * Value to describe the MIDAS node identifier in a message
	 */
	public static final String MIDAS_ID 			= "MIDAS_ID";
	
	/**
	 * Value to describe the type of node in a message
	 */
	public static final String NODE_TYPE_ELEM 		= "NODE_TYPE";
	
	/**
	 * Value to describe the IP address in a message
	 */
	public static final String IP_ADDRESS_ELEM 		= "IP_ADDRESS";
	
	/**
	 * Value to describe the name of the proxy in a message
	 */
	public static final String PROXY_SETTING 		= "PROXY";
	
	/**
	 * Sets the role of the node.
	 * <ul>
	 * <li>Central Node:0
	 * <li>Gateway Node:1
	 * <li>User Node:2
	 * </ul>
	 */
	public int NODE_TYPE 									= -1;
	
	/**
	 * Sets the role of the node as Central Node
	 */
	public static final int CENTRAL_NODE 					= 0;
	
	/**
	 * Sets the role of the node as Gateway Node
	 */
	public static final int GATEWAY_NODE 					= 1;
	
	/**
	 * Sets the role of the node as User Node
	 */
	public static final int USER_NODE 						= 2;
	
	/**
	 * Sets the role of the node as Nokia User Node
	 */
	public static final int NOKIA_USER_NODE 				= 3;
	
	/**
	 * Provides the information about if the node role of the MIDAS node based
	 * on the value established in the properties configuration file.
	 * 
	 * @return The role of the MIDAS node.
	 * 				<ul>
	 * 				<li>Central Node:0
	 * 				<li>Gateway Node:1
	 *				<li>User Node:2
	 *				</ul>
	 */
	public int getNodeType()
    {
		return NODE_TYPE;
    }
	
	/**
	 * CBR node id
	 */
	public int CBR_NODE_ID							= 0;

	/**
	 * Provides the CBR node id for the CBR Server based on the value
	 * established in the properties configuration file.
	 * 
	 * @return CBR node id
	 */
	public int getCBRNodeID()
	{
		return CBR_NODE_ID;
	}

	/**
	 * Value to describe TCP port number for the CBR Server
	 */
	public int CBR_SERVER_PORT						= 0;
	

	/**
	 * Value to describe IP address for the CBR Server
	 */
	public String CBR_SERVER_IP						=  "127.0.0.1";
	
	/**
	 * Value to describe TCP port number for the 'firewalled' mode.
	 */
	public int CBR_FMODE_PORT						= 0;
	
	/**
	 * Value to describe IP address for the 'firewalled' mode.
	 */
	public String CBR_FMODE_IP						= "127.0.0.1";

	/**
	 * Provides the TCP port number for the CBR Server port based on the value
	 * established in the properties configuration file.
	 * 
	 * @return The TCP port number for the CBR Server port
	 */
	public int getCBRServerPort()
	{
		return CBR_SERVER_PORT;
	}
	
	/**
	 * Provides the IP address for the CBR Server IP address based on the value
	 * established in the properties configuration file.
	 * 
	 * @return The IP address for the CBR Server IP address
	 */
	public String getCBRServerIP() {
		return CBR_SERVER_IP;
	}
	
	/**
	 * Provides the TCP port number for the 'firewalled' mode based on
	 * the value established in the properties configuration file.
	 * 
	 * @return The TCP port number for the 'firewalled' mode
	 */
	public int getCBRFModePort()
	{
		return CBR_FMODE_PORT;
	}
	
	/**
	 * Provides the IP address for the 'firewalled' mode based on
	 * the value established in the properties configuration file.
	 * 
	 * @return The IP address for the 'firewalled' mode
	 */
	public String getCBRFModeIP() {
		return CBR_FMODE_IP;
	}
	
    /**
	 * Configure the CRT with the parameters established in the properties 
	 * configuration file.
	 * 
	 * @throws CrtException If an error occurred configuring the CRT
	 */
	public void configure() throws CrtException
	{
		CfgLogging.logEvent(CfgLogging.LOG_MCALL, Logger.COMPONENT_CRT, CfgLogging.SEV_DEBUG, "Constants.configure()");		
		
		Properties middlewareProperties;
	    /* Loading the properties file
	     */
	    try 
	    {	    	
	    	FileInputStream file = new FileInputStream(CONFIGURATION_FILE);

	    	middlewareProperties = new Properties();
	    	middlewareProperties.load(file);
	    	file.close();
	    	
	    	//Fixing the variables	    	
	    	NODE_ID = middlewareProperties.getProperty("nodeId").trim();
	    	
	    	//Network interfaces
	    	ETHERNET = middlewareProperties.getProperty("eth", "").trim();
	    	THIRDG = middlewareProperties.getProperty("3g", "").trim();
	    	WIFI = middlewareProperties.getProperty("wlan", "").trim();	    	
	    	BT = middlewareProperties.getProperty("bt", "").trim();
	    	
	    	//Wireless parametes
	    	IP_ADDRESS 	    = middlewareProperties.getProperty("address", "" ).trim();
	    	NETMASK 		= middlewareProperties.getProperty("netmask", "").trim();
	    	NET_ADDRESS 	= middlewareProperties.getProperty("network", "").trim();
	    	SSID 			= middlewareProperties.getProperty("SSID", "").trim();
	    	MODE 			= middlewareProperties.getProperty("mode", "").toLowerCase().trim();
	    	KEY 			= middlewareProperties.getProperty("key", "").trim();
	    	
	    	//Jxta parameters	    	
	    	CENTRAL_NODE_IP	= middlewareProperties.getProperty("CentralNodeIP", "").toLowerCase().trim();
	    	NODE_TYPE 		= Integer.parseInt(middlewareProperties.getProperty("NodeType", "2").trim());

	    	//CBR parameters
	    	CBR_NODE_ID		= Integer.parseInt(middlewareProperties.getProperty("CBRNodeID", "-1").trim());
	    	CBR_SERVER_PORT		= Integer.parseInt(middlewareProperties.getProperty("CBRServerPort", "8889").trim());
	    	CBR_SERVER_IP		= middlewareProperties.getProperty("CBRServerIP", "127.0.0.1").trim();
	    	CBR_FMODE_PORT		= Integer.parseInt(middlewareProperties.getProperty("CBRFModePort", "8083").trim());
	    	CBR_FMODE_IP		= middlewareProperties.getProperty("CBRFModeIP", "127.0.0.1").trim();
	    	
	    	//Nokia polling parameters
	    	POLLING_INTERVAL 	= Integer.parseInt(middlewareProperties.getProperty("PollingInterval", "1000").trim());
	    	HTTP_TIMEOUT        = Integer.parseInt(middlewareProperties.getProperty("HttpTimeout", "5000").trim());
	    	
	    	//Proxy settings
	    	PROXY_NAME 	      = middlewareProperties.getProperty("proxyName", "").toLowerCase().trim();
	    	PROXY_PORT        = middlewareProperties.getProperty("proxyPort", "").toLowerCase().trim();
	    	
	    	//Public IP address
	    	PUBLIC_IP_ADDRESS = middlewareProperties.getProperty("PublicIPAddress", "").toLowerCase().trim();
	    	
	    	/* Last, if there are properties defined with -D when
			 * starting the middleware, use that instead;  Such properties
			 * should have the prefix midas.mw.crt
			*/	    	
			Enumeration k = middlewareProperties.keys();
			while (k.hasMoreElements()) {
				String key = (String) k.nextElement();				
				String val;
				if ((val = System.getProperty("midas.mw.crt." + key)) != null)
				{
					if (key.equals("nodeId"))
						NODE_ID = val;					
					else if (key.equals("NodeType"))
						NODE_TYPE = Integer.parseInt(val);
					else if (key.equals("CentralNodeIP"))
						NODE_TYPE = Integer.parseInt(val);					
					else if (key.equals("CBRServerPort"))
						CBR_SERVER_PORT = Integer.parseInt(val);
					
				}
			}

	    } catch (FileNotFoundException fnfe) {
	    	CfgError.errorReporting(CfgError.ERR_OPER, Logger.COMPONENT_CRT, CfgError.SEV_FATAL, 
					"Constants.configure(). Failed to get the Properties file: '" + 
					fnfe.getMessage() + "'", null);
	      	throw new CrtException ();
	    } catch (IOException ioe) {
	    	CfgError.errorReporting(CfgError.ERR_OPER, "CRT.Constants", CfgError.SEV_FATAL, 
					"Constants.configure(). Failed to read the Properties file: '" + 
					ioe.getMessage() + "'", null);
	    	throw new CrtException ();
	    }	    
	}
}
